package Export;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import DataModel.Feature;
import DataModel.LociHolder;
import Viewer.Viewer;

/**
 * This class implements the fastA exporter. It contains functions to write the sequences in plus/minus direction.
 * The {@link Viewer} is needed for the information about track index and sequences.<br>
 * 
 * Also see:<br>
 * <a href="http://www.ebi.ac.uk/help/formats.html#fasta">http://www.ebi.ac.uk/help/formats.html#fasta</a>
 *
 * @author Stefan Lorenz<br>
 * <br>26.11.2012
 */
public class ExportSequence {

    /**
     * Viewer
     */
    private Viewer viewer;
    /**
     * Type of sequence
     */
    private String event;
    /**
     * Path of output file
     */
    private String outputPath;

    /**
     * Constructor of the FastA exporter
     * @param frame
     * @param event
     * @param outputPath
     */
    public ExportSequence(Viewer frame, String event, String outputPath) {
	this.viewer = frame;
	this.outputPath = outputPath;
	this.event = event;

	File file = new File(this.outputPath);

	if (!(file.getName().endsWith(".fasta") || file.getName().endsWith(".fas") || file.getName().endsWith(".fa")))
	    file = new File(outputPath + ".fasta");

	try {
	    BufferedWriter bwriter = new BufferedWriter(new FileWriter(file));

	    for (int i = 0; i < viewer.getSelectedFeatureList().size(); i++) {
		Feature l = viewer.getSelectedFeatureList().get(i);
		ArrayList<String> seq = new ArrayList<String>();
		    
		// if the track of the feature ist anchored to an sequence containing track use this sequence
		if (this.viewer.getLoadedTracks()[this.viewer.getTrackPositionLines(l.getTrackIndex()).getAnchor()].getTypeOfFile().equals("gbk") ||
			this.viewer.getLoadedTracks()[this.viewer.getTrackPositionLines(l.getTrackIndex()).getAnchor()].getTypeOfFile().equals("fasta") ||
			this.viewer.getLoadedTracks()[this.viewer.getTrackPositionLines(l.getTrackIndex()).getAnchor()].getTypeOfFile().equals("fas") ||
			this.viewer.getLoadedTracks()[this.viewer.getTrackPositionLines(l.getTrackIndex()).getAnchor()].getTypeOfFile().equals("fa") ||
			this.viewer.getLoadedTracks()[this.viewer.getTrackPositionLines(l.getTrackIndex()).getAnchor()].getTypeOfFile().equals("embl")){
		
		    seq = ((LociHolder) this.viewer.getLoadedTracks()[this.viewer.getTrackPositionLines(l.getTrackIndex()).getAnchor()]).getSplicedSequenceFromTo(((LociHolder) this.viewer.getLoadedTracks()[this.viewer.getTrackPositionLines(l.getTrackIndex()).getAnchor()]).getListOfLoci().get(0).getLocusName(), l.getListOfPositions());
	    	}
		else{
		    System.err.println("No Sequence in track " + l.getTrackIndex() + " for " + l.getName() + " " + l.getStart() + ".." + l.getStop());
		    continue;
		}
		if(seq.get(0) == null){
		    System.err.println("No Sequence in track " + l.getTrackIndex() + " for " + l.getName() + " " + l.getStart() + ".." + l.getStop());
		    continue;
		}
		bwriter.write(">" + l.getName() + " | " + l.getAbsoultePositions().getStart() + ".." + l.getAbsoultePositions().getStop() + " | " + l.getType() + " | " + l.getStrand());

		String sequence = "";
		for (int j = 0; j < seq.size(); j++) {
		    sequence += seq.get(j).toUpperCase();
		}
		

		if (this.event.equals("DNA")) {
		    writeFastA(bwriter, sequence);
		} else if (this.event.equals("RNA")) {
		    writeFastA(bwriter, sequence.replace("T", "U"));
		} else if (this.event.equals("AA")) {
		    StringBuilder reverseSeq = new StringBuilder();
		    for (int x = 0; x < sequence.length(); x++) {
			reverseSeq.append(this.viewer.getComplementOfBase(sequence.charAt(x)));
		    }
		    reverseSeq.reverse();

		    StringBuilder sb = new StringBuilder();
		    for (int k = 0; k < sequence.length() - 2; k += 3) {
			if (l.getStrand().equals("+"))
			    sb.append(viewer.getAminoAcidTable().get(sequence.substring(k, k + 3)));
			else
			    sb.append(viewer.getAminoAcidTable().get(reverseSeq.substring(k, k + 3)));

		    }
		    writeFastA(bwriter, sb.toString());
		}
	    }
	    bwriter.flush();
	    bwriter.close();

	} catch (IOException e1) {
	    // TODO Auto-generated catch block
	    e1.printStackTrace();
	}
    }

    /**
     * Writes sequence in FastA format in block of 40 nucleotides
     * 
     * @param bwriter
     * @param seq
     * @throws IOException
     */
    private void writeFastA(BufferedWriter bwriter, String seq) throws IOException {
	int counter = 0;
	for (int k = 0; k < seq.length() - 40; k += 40) {
	    bwriter.newLine();
	    bwriter.write(seq.substring(k, k + 40));
	    bwriter.flush();
	    counter++;
	}
	bwriter.newLine();
	bwriter.write(seq.substring(counter * 40));
	bwriter.newLine();
	bwriter.flush();
    }

}
